#include "pch.h"

void initJittering(osg::StateSet *ss)
{
	// create a 3D texture with hw mipmapping
	osg::Texture3D* texture3D = new osg::Texture3D;
	texture3D->setFilter(osg::Texture3D::MIN_FILTER, osg::Texture3D::NEAREST);
	texture3D->setFilter(osg::Texture3D::MAG_FILTER, osg::Texture3D::NEAREST);
	texture3D->setWrap(osg::Texture3D::WRAP_S, osg::Texture3D::REPEAT);
	texture3D->setWrap(osg::Texture3D::WRAP_T, osg::Texture3D::REPEAT);
	texture3D->setWrap(osg::Texture3D::WRAP_R, osg::Texture3D::REPEAT);
	texture3D->setUseHardwareMipMapGeneration(true);

	const unsigned int size = 2;
	const unsigned int depth = 48;
	texture3D->setTextureSize(size, size, depth);

	// then create the 3d image to fill with jittering data
	osg::Image* image3D = new osg::Image;
	unsigned char *data3D = new unsigned char[size * size * depth * 4];

	for (unsigned int s = 0; s < size; ++s)
	{
		for (unsigned int t = 0; t < size; ++t)
		{
			//float v[4], d[4];

			for (unsigned int r = 0; r < depth; ++r)
			{
				//const int x = r % (gridW / 2);
				//const int y = (gridH - 1) - (r / (gridW / 2));

				//// Generate points on a  regular gridW x gridH rectangular
				//// grid.   We  multiply  x   by  2  because,  we  treat  2
				//// consecutive x  each loop iteration.  Add 0.5f  to be in
				//// the center of the pixel. x, y belongs to [ 0.0, 1.0 ].
				//v[0] = float(x * 2 + 0.5f) / gridW;
				//v[1] = float(y + 0.5f) / gridH;
				//v[2] = float(x * 2 + 1 + 0.5f) / gridW;
				//v[3] = v[1];

				//// Jitter positions. ( 0.5f / w ) == ( 1.0f / 2*w )
				//v[0] += ((float)rand() * 2.f / RAND_MAX - 1.f) * (0.5f / gridW);
				//v[1] += ((float)rand() * 2.f / RAND_MAX - 1.f) * (0.5f / gridH);
				//v[2] += ((float)rand() * 2.f / RAND_MAX - 1.f) * (0.5f / gridW);
				//v[3] += ((float)rand() * 2.f / RAND_MAX - 1.f) * (0.5f / gridH);

				//// Warp to disk; values in [-1,1]
				//d[0] = sqrtf(v[1]) * cosf(2.f * 3.1415926f * v[0]);
				//d[1] = sqrtf(v[1]) * sinf(2.f * 3.1415926f * v[0]);
				//d[2] = sqrtf(v[3]) * cosf(2.f * 3.1415926f * v[2]);
				//d[3] = sqrtf(v[3]) * sinf(2.f * 3.1415926f * v[2]);

				// store d into unsigned values [0,255]
				const unsigned int tmp = ((r * size * size) + (t * size) + s) * 4;
				data3D[tmp + 0] = rand()%256;
				data3D[tmp + 1] = rand()%256;
				data3D[tmp + 2] = rand()%256;
				data3D[tmp + 3] = 1;

			}
		}
	}

	// the GPU Gem implementation uses a NV specific internal texture format (GL_SIGNED_RGBA_NV)
	// In order to make it more generic, we use GL_RGBA4 which should be cross platform.
#ifdef GL_RGBA4
	GLenum internalTextureFormat = GL_RGBA4;
#else
// OpenGLES 1.1 doesn't define GL_RGBA4, so we'll just assume RGBA
	GLenum internalTextureFormat = GL_RGBA;
#endif
	image3D->setImage(size, size, depth, internalTextureFormat, GL_RGBA, GL_UNSIGNED_BYTE, data3D, osg::Image::USE_NEW_DELETE);

	texture3D->setImage(image3D);

	ss->setTextureAttributeAndModes(3, texture3D, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
	ss->setTextureMode(3, GL_TEXTURE_GEN_S, osg::StateAttribute::ON);
	ss->setTextureMode(3, GL_TEXTURE_GEN_T, osg::StateAttribute::ON);
	ss->setTextureMode(3, GL_TEXTURE_GEN_R, osg::StateAttribute::ON);

}
